home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 2.toast / pc / sample code / quicktime / quicktimeintro / moviesprites / application files / comapplication.c next >
Encoding:
Text File  |  2000-10-06  |  14.9 KB  |  596 lines

  1. //////////
  2. //
  3. //    File:        ComApplication.c
  4. //
  5. //    Contains:    Application-specific code for basic QuickTime movie display and control.
  6. //
  7. //    Written by:    Tim Monroe
  8. //                Based on the QTShell code written by Tim Monroe, which in turn was based on the MovieShell
  9. //                code written by Kent Sandvik (Apple DTS). This current version is now very far removed from
  10. //                MovieShell.
  11. //
  12. //    Copyright:    © 1999 by Apple Computer, Inc., all rights reserved.
  13. //
  14. //    Change History (most recent first):
  15. //       
  16. //       <2>         03/17/00    rtm        made changes to get things running under CarbonLib
  17. //       <1>         11/05/99    rtm        first file
  18. //
  19. //////////
  20.  
  21. //////////
  22. //
  23. // header files
  24. //
  25. //////////
  26.  
  27. #include "ComApplication.h"
  28. #include "QTSprites.h"
  29.  
  30.  
  31. //////////
  32. //
  33. // global variables
  34. //
  35. //////////
  36.  
  37. extern Boolean            gUseBackgroundPicture;
  38.  
  39. #if TARGET_OS_MAC
  40. AEEventHandlerUPP        gHandleOpenAppAEUPP;                    // UPPs for our Apple event handlers
  41. AEEventHandlerUPP        gHandleOpenDocAEUPP;
  42. AEEventHandlerUPP        gHandlePrintDocAEUPP;
  43. AEEventHandlerUPP        gHandleQuitAppAEUPP;
  44. extern Boolean            gAppInForeground;                        // is our application in the foreground?    
  45. #endif
  46.  
  47. #if TARGET_OS_WIN32
  48. extern HWND                ghWnd;                                    // the MDI frame window; this window has the menu bar
  49. #endif
  50.  
  51.  
  52. //////////
  53. //
  54. // QTApp_Init
  55. // Do any application-specific initialization.
  56. //
  57. // The theStartPhase parameter determines which "phase" of application start-up is executed,
  58. // *before* the MDI frame window is created or *after*. This distinction is relevant only on
  59. // Windows, so on MacOS, you should always use kInitAppPhase_BothPhases.
  60. //
  61. //////////
  62.  
  63. void QTApp_Init (UInt32 theStartPhase)
  64. {
  65.     // do any start-up activities that should occur before the MDI frame window is created
  66.     if (theStartPhase & kInitAppPhase_BeforeCreateFrameWindow) {
  67.         // check to make sure that QuickTime wired sprites are available;
  68.         // we depend on these features  
  69.         if (!QTUtils_HasWiredSprites())
  70.             QTFrame_QuitFramework();
  71.  
  72. #if TARGET_OS_MAC
  73.         // make sure that the Apple Event Manager is available; install handlers for required Apple events
  74.         QTApp_InstallAppleEventHandlers();
  75. #endif
  76.     }
  77.  
  78.     // do any start-up activities that should occur after the MDI frame window is created
  79.     if (theStartPhase & kInitAppPhase_AfterCreateFrameWindow) {
  80. #if TARGET_OS_WIN32
  81.         // on Windows, open as movie documents any files specified on the command line
  82.         SendMessage(ghWnd, WM_OPENDROPPEDFILES, 0L, 0L);
  83. #endif
  84.     }
  85. }
  86.  
  87.  
  88. //////////
  89. //
  90. // QTApp_Stop
  91. // Do any application-specific shut-down.
  92. //
  93. // The theStopPhase parameter determines which "phase" of application shut-down is executed,
  94. // *before* any open movie windows are destroyed or *after*.
  95. //
  96. //////////
  97.  
  98. void QTApp_Stop (UInt32 theStopPhase)
  99. {    
  100.     // do any shut-down activities that should occur before the movie windows are destroyed
  101.     if (theStopPhase & kStopAppPhase_BeforeDestroyWindows) {
  102.         
  103.     }
  104.     
  105.     // do any shut-down activities that should occur after the movie windows are destroyed
  106.     if (theStopPhase & kStopAppPhase_AfterDestroyWindows) {
  107. #if TARGET_OS_MAC
  108.         // dispose of routine descriptors for Apple event handlers
  109.         DisposeAEEventHandlerUPP(gHandleOpenAppAEUPP);
  110.         DisposeAEEventHandlerUPP(gHandleOpenDocAEUPP);
  111.         DisposeAEEventHandlerUPP(gHandlePrintDocAEUPP);
  112.         DisposeAEEventHandlerUPP(gHandleQuitAppAEUPP);
  113. #endif
  114.     
  115.     }
  116. }
  117.  
  118.  
  119. //////////
  120. //
  121. // QTApp_Idle
  122. // Do any processing that can/should occur at idle time.
  123. //
  124. //////////
  125.  
  126. void QTApp_Idle (WindowReference theWindow)
  127. {
  128.     WindowObject         myWindowObject = NULL;
  129.     GrafPtr             mySavedPort;
  130.     //Cursor                myArrow;
  131.     
  132.     GetPort(&mySavedPort);
  133.     MacSetPort(QTFrame_GetPortFromWindowReference(theWindow));
  134.     
  135.     myWindowObject = QTFrame_GetWindowObjectFromWindow(theWindow);
  136.     if (myWindowObject != NULL) {
  137.         MovieController        myMC = NULL;
  138.     
  139.         myMC = (**myWindowObject).fController;
  140.         if (myMC != NULL) {
  141.             
  142.             // run any idle-time tasks for the movie
  143.             
  144. #if TARGET_OS_MAC
  145.             // restore the cursor to the arrow
  146.             // if it's outside the front movie window or outside the window's visible region
  147.             if (theWindow == QTFrame_GetFrontMovieWindow()) {
  148.                 Rect            myRect;
  149.                 Point            myPoint;
  150.                 RgnHandle        myVisRegion;
  151.                 Cursor            myArrow;
  152.                 
  153.                 GetMouse(&myPoint);
  154.                 myVisRegion = NewRgn();
  155.                 GetPortVisibleRegion(QTFrame_GetPortFromWindowReference(theWindow), myVisRegion);
  156.                 GetWindowPortBounds(theWindow, &myRect);
  157.                 if (!MacPtInRect(myPoint, &myRect) || !PtInRgn(myPoint, myVisRegion))
  158.                     MacSetCursor(GetQDGlobalsArrow(&myArrow));
  159.                     
  160.                 DisposeRgn(myVisRegion);
  161.             }
  162. #endif // TARGET_OS_MAC
  163.         }
  164.     }
  165.     
  166.     // ***insert application-specific idle-time processing here***
  167.     
  168.     MacSetPort(mySavedPort);
  169. }
  170.  
  171.  
  172. //////////
  173. //
  174. // QTApp_Draw
  175. // Update the specified window.
  176. //
  177. //////////
  178.  
  179. void QTApp_Draw (WindowReference theWindow, Rect *theRefreshArea)
  180. {
  181. #pragma unused(theRefreshArea)
  182.  
  183.     GrafPtr             mySavedPort;
  184.     
  185.     GetPort(&mySavedPort);
  186.     MacSetPort(QTFrame_GetPortFromWindowReference(theWindow));
  187.     
  188.     BeginUpdate(QTFrame_GetWindowFromWindowReference(theWindow));
  189.     //EraseRect(theRefreshArea);        // this is important only for non-rectangular movies
  190.     
  191.     // ***insert application-specific drawing here***
  192.     
  193.     // draw the movie controller and its movie
  194.     MCDoAction(QTFrame_GetMCFromWindow(theWindow), mcActionDraw, theWindow);
  195.     
  196.     EndUpdate(QTFrame_GetWindowFromWindowReference(theWindow));
  197.     MacSetPort(mySavedPort);
  198. }
  199.  
  200.  
  201. //////////
  202. //
  203. // QTApp_HandleContentClick
  204. // Handle mouse button clicks in the specified window.
  205. //
  206. //////////
  207.  
  208. void QTApp_HandleContentClick (WindowReference theWindow, EventRecord *theEvent)
  209. {
  210. #pragma unused(theEvent)
  211.  
  212.     GrafPtr             mySavedPort;
  213.     
  214.     GetPort(&mySavedPort);
  215.     MacSetPort(QTFrame_GetPortFromWindowReference(theWindow));
  216.     
  217.     // ***insert application-specific content-click processing here***
  218.  
  219.     MacSetPort(mySavedPort);
  220. }
  221.  
  222.  
  223. //////////
  224. //
  225. // QTApp_HandleKeyPress
  226. // Handle application-specific key presses.
  227. // Returns true if the key press was handled, false otherwise.
  228. //
  229. //////////
  230.  
  231. Boolean QTApp_HandleKeyPress (char theCharCode)
  232. {
  233.     Boolean        isHandled = true;
  234.     
  235.     switch (theCharCode) {
  236.     
  237.         // ***insert application-specific key-press processing here***
  238.  
  239.         default:
  240.             isHandled = false;
  241.             break;
  242.     }
  243.  
  244.     return(isHandled);
  245. }
  246.  
  247.  
  248. //////////
  249. //
  250. // QTApp_HandleMenu
  251. // Handle selections in the application's menus.
  252. //
  253. // The theMenuItem parameter is a UInt16 version of the Windows "menu item identifier". 
  254. // When called from Windows, theMenuItem is simply the menu item identifier passed to the window procedure.
  255. // When called from MacOS, theMenuItem is constructed like this:
  256. //     *high-order 8 bits == the Macintosh menu ID (1 thru 256)
  257. //     *low-order 8 bits == the Macintosh menu item (sequential from 1 to ordinal of last menu item in menu)
  258. // In this way, we can simplify the menu-handling code. There are, however, some limitations, mainly that
  259. // the menu item identifiers on Windows must be derived from the Mac values. 
  260. //
  261. //////////
  262.  
  263. Boolean QTApp_HandleMenu (UInt16 theMenuItem)
  264. {
  265.     Boolean                myIsHandled = false;            // false => allow caller to process the menu item
  266.         
  267.     switch (theMenuItem) {
  268.     
  269.         case IDM_MAKE_SPRITE_MOVIE:
  270.             QTSprites_CreateSpritesMovie();
  271.             myIsHandled = true;
  272.             break;
  273.  
  274.         case IDM_USE_BACKGROUND_IMAGE:
  275.             gUseBackgroundPicture = !gUseBackgroundPicture;
  276.             myIsHandled = true;
  277.             break;
  278.             
  279.         default:
  280.             break;
  281.             
  282.     } // switch (theMenuItem)
  283.     
  284.     return(myIsHandled);
  285. }
  286.  
  287.  
  288. //////////
  289. //
  290. // QTApp_AdjustMenus
  291. // Adjust state of items in the application's menus.
  292. //
  293. // Currently, the Mac application has only one app-specific menu ("Test"); you could change that.
  294. //
  295. //////////
  296.  
  297. void QTApp_AdjustMenus (WindowReference theWindow, MenuReference theMenu)
  298. {
  299. #if TARGET_OS_MAC
  300. #pragma unused(theMenu)
  301. #endif
  302.  
  303.     MenuReference        myMenu;
  304.     
  305. #if TARGET_OS_WIN32
  306.     myMenu = theMenu;
  307. #endif
  308. #if TARGET_OS_MAC
  309.     myMenu = GetMenuHandle(kTestMenuResID);
  310. #endif
  311.     
  312.     QTFrame_SetMenuItemCheck(myMenu, IDM_USE_BACKGROUND_IMAGE, gUseBackgroundPicture);
  313.  
  314. }
  315.  
  316.  
  317. //////////
  318. //
  319. // QTApp_HandleEvent
  320. // Perform any application-specific event loop actions.
  321. //
  322. // Return true to indicate that we've completely handled the event here, false otherwise.
  323. //
  324. //////////
  325.  
  326. Boolean QTApp_HandleEvent (EventRecord *theEvent)
  327. {
  328. #pragma unused(theEvent)
  329.  
  330.     // ***insert application-specific event handling here***
  331.     
  332.     return(false);            // no-op for now
  333. }
  334.  
  335.  
  336. //////////
  337. //
  338. // QTApp_SetupController
  339. // Configure the movie controller.
  340. //
  341. //////////
  342.  
  343. void QTApp_SetupController (MovieController theMC)
  344. {
  345.     long            myControllerFlags;
  346.     
  347.     // CLUT table use
  348.     MCDoAction(theMC, mcActionGetFlags, &myControllerFlags);
  349.     MCDoAction(theMC, mcActionSetFlags, (void *)(myControllerFlags | mcFlagsUseWindowPalette));
  350.  
  351.     // enable keyboard event handling
  352.     MCDoAction(theMC, mcActionSetKeysEnabled, (void *)true);
  353.     
  354.     // disable drag support
  355.     MCDoAction(theMC, mcActionSetDragEnabled, (void *)false);
  356. }
  357.  
  358.  
  359. //////////
  360. //
  361. // QTApp_SetupWindowObject
  362. // Do any application-specific initialization of the window object.
  363. //
  364. //////////
  365.  
  366. void QTApp_SetupWindowObject (WindowObject theWindowObject)
  367. {
  368.     ApplicationDataHdl        myAppData = NULL;
  369.  
  370.     if (theWindowObject == NULL)
  371.         return;
  372.         
  373.     myAppData = QTSprites_InitWindowData(theWindowObject);
  374.     (**theWindowObject).fAppData = (Handle)myAppData;
  375. }
  376.  
  377.  
  378. //////////
  379. //
  380. // QTApp_RemoveWindowObject
  381. // Do any application-specific clean-up of the window object.
  382. //
  383. //////////
  384.  
  385. void QTApp_RemoveWindowObject (WindowObject theWindowObject)
  386. {
  387. #pragma unused(theWindowObject)
  388.     
  389.     if (theWindowObject != NULL)
  390.         QTSprites_DumpWindowData(theWindowObject);
  391.  
  392.     // QTFrame_DestroyMovieWindow in MacFramework.c or QTFrame_MovieWndProc in WinFramework.c
  393.     // releases the window object itself
  394. }
  395.  
  396.  
  397. //////////
  398. //
  399. // QTApp_MCActionFilterProc 
  400. // Intercept some actions for the movie controller.
  401. //
  402. // NOTE: The theRefCon parameter is a handle to a window object record.
  403. //
  404. //////////
  405.  
  406. PASCAL_RTN Boolean QTApp_MCActionFilterProc (MovieController theMC, short theAction, void *theParams, long theRefCon)
  407. {
  408. #pragma unused(theMC, theParams)
  409.  
  410.     Boolean                isHandled = false;            // false => allow controller to process the action
  411.     WindowObject        myWindowObject = NULL;
  412.     
  413.     myWindowObject = (WindowObject)theRefCon;
  414.     if (myWindowObject == NULL)
  415.         return(isHandled);
  416.         
  417.     switch (theAction) {
  418.     
  419.         // handle window resizing
  420.         case mcActionControllerSizeChanged:
  421.             if (MCIsControllerAttached(theMC) == 1)
  422.                 QTFrame_SizeWindowToMovie(myWindowObject);
  423.             break;
  424.  
  425.         // handle idle events
  426.         case mcActionIdle:
  427.             QTApp_Idle((**myWindowObject).fWindow);
  428.             break;
  429.             
  430.         // handle mouse-down events
  431.         case mcActionMouseDown:
  432.             isHandled = QTSprites_HitTestSprites(myWindowObject, (EventRecord *)theParams);
  433.             break;
  434.             
  435.         default:
  436.             break;
  437.             
  438.     } // switch (theAction)
  439.     
  440.     return(isHandled);    
  441. }
  442.  
  443.  
  444. #if TARGET_OS_MAC
  445. ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  446. //
  447. // Apple Event functions.
  448. //
  449. // Use these functions to install handlers for Apple Events and to handle those events.
  450. //
  451. ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  452.  
  453. //////////
  454. //
  455. // QTApp_InstallAppleEventHandlers 
  456. // Install handlers for Apple Events.
  457. //
  458. //////////
  459.  
  460. void QTApp_InstallAppleEventHandlers (void)
  461. {
  462.     long        myAttrs;
  463.     OSErr        myErr = noErr;
  464.     
  465.     // see whether the Apple Event Manager is available in the present operating environment;
  466.     // if it is, install handlers for the four required Apple Events
  467.     myErr = Gestalt(gestaltAppleEventsAttr, &myAttrs);
  468.     if (myErr == noErr) {
  469.         if (myAttrs & (1L << gestaltAppleEventsPresent)) {
  470.             // create routine descriptors for the Apple event handlers
  471.             gHandleOpenAppAEUPP = NewAEEventHandlerUPP(QTApp_HandleOpenApplicationAppleEvent);
  472.             gHandleOpenDocAEUPP = NewAEEventHandlerUPP(QTApp_HandleOpenDocumentAppleEvent);
  473.             gHandlePrintDocAEUPP = NewAEEventHandlerUPP(QTApp_HandlePrintDocumentAppleEvent);
  474.             gHandleQuitAppAEUPP = NewAEEventHandlerUPP(QTApp_HandleQuitApplicationAppleEvent);
  475.             
  476.             // install the handlers
  477.             AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, gHandleOpenAppAEUPP, 0L, false);
  478.             AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, gHandleOpenDocAEUPP, 0L, false);
  479.             AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments, gHandlePrintDocAEUPP, 0L, false);
  480.             AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, gHandleQuitAppAEUPP, 0L, false);
  481.         }
  482.     }
  483. }
  484.         
  485.         
  486. //////////
  487. //
  488. // QTApp_HandleOpenApplicationAppleEvent 
  489. // Handle the open-application Apple Events.
  490. //
  491. //////////
  492.  
  493. PASCAL_RTN OSErr QTApp_HandleOpenApplicationAppleEvent (const AppleEvent *theMessage, AppleEvent *theReply, unsigned long theRefcon)            
  494. {
  495. #pragma unused(theMessage, theReply, theRefcon)
  496.     
  497.     // we don't need to do anything special when opening the application
  498.     return(noErr);
  499. }
  500.  
  501.  
  502. //////////
  503. //
  504. // QTApp_HandleOpenDocumentAppleEvent 
  505. // Handle the open-document Apple Events. This is based on Inside Macintosh: IAC, pp. 4-15f.
  506. //
  507. // Here we process an Open Documents AE only for files of type MovieFileType.
  508. //
  509. //////////
  510.  
  511. PASCAL_RTN OSErr QTApp_HandleOpenDocumentAppleEvent (const AppleEvent *theMessage, AppleEvent *theReply, unsigned long theRefcon)            
  512. {
  513. #pragma unused(theReply, theRefcon)
  514.  
  515.     long            myIndex;
  516.     long            myItemsInList;
  517.     AEKeyword        myKeyWd;
  518.     AEDescList          myDocList;
  519.     long            myActualSize;
  520.     DescType        myTypeCode;
  521.     FSSpec            myFSSpec;
  522.     OSErr            myIgnoreErr = noErr;
  523.     OSErr            myErr = noErr;
  524.     
  525.     // get the direct parameter and put it into myDocList
  526.     myDocList.dataHandle = NULL;
  527.     myErr = AEGetParamDesc(theMessage, keyDirectObject, typeAEList, &myDocList);
  528.     
  529.     // count the descriptor records in the list
  530.     if (myErr == noErr)
  531.         myErr = AECountItems(&myDocList, &myItemsInList);
  532.     else
  533.         myItemsInList = 0;
  534.     
  535.     // open each specified file
  536.     for (myIndex = 1; myIndex <= myItemsInList; myIndex++)
  537.         if (myErr == noErr) {
  538.             myErr = AEGetNthPtr(&myDocList, myIndex, typeFSS, &myKeyWd, &myTypeCode, (Ptr)&myFSSpec, sizeof(myFSSpec), &myActualSize);
  539.             if (myErr == noErr) {
  540.                 FInfo        myFinderInfo;
  541.             
  542.                 // verify that the file type is MovieFileType; to do this, get the Finder information
  543.                 myErr = FSpGetFInfo(&myFSSpec, &myFinderInfo);    
  544.                 if (myErr == noErr) {
  545.                     if (myFinderInfo.fdType == MovieFileType)
  546.                         // we've got a movie file; just open it
  547.                         QTFrame_OpenMovieInWindow(NULL, &myFSSpec);
  548.                 }
  549.             }
  550.         }
  551.  
  552.     if (myDocList.dataHandle)
  553.         myIgnoreErr = AEDisposeDesc(&myDocList);
  554.     
  555.     // make sure we open the document in the foreground        
  556.     gAppInForeground = true;
  557.     return(myErr);
  558. }
  559.  
  560.  
  561. //////////
  562. //
  563. // QTApp_HandlePrintDocumentAppleEvent 
  564. // Handle the print-document Apple Events.
  565. //
  566. // NOT YET IMPLEMENTED.
  567. //
  568. //////////
  569.  
  570. PASCAL_RTN OSErr QTApp_HandlePrintDocumentAppleEvent (const AppleEvent *theMessage, AppleEvent *theReply, unsigned long theRefcon)            
  571. {
  572. #pragma unused(theMessage, theReply, theRefcon)
  573.  
  574.     return(errAEEventNotHandled);
  575. }
  576.  
  577.  
  578. //////////
  579. //
  580. // QTApp_HandleQuitApplicationAppleEvent 
  581. // Handle the quit-application Apple Events.
  582. //
  583. //////////
  584.  
  585. PASCAL_RTN OSErr QTApp_HandleQuitApplicationAppleEvent (const AppleEvent *theMessage, AppleEvent *theReply, unsigned long theRefcon)            
  586. {
  587. #pragma unused(theMessage, theReply, theRefcon)
  588.  
  589.     // close down the entire framework and application
  590.     QTFrame_QuitFramework();
  591.     return(noErr);
  592. }
  593. #endif // TARGET_OS_MAC
  594.  
  595.  
  596.